package com.crocodileQ.blog.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import com.crocodileQ.blog.domain.dto.BlogArticleTagsDto;
import com.crocodileQ.blog.domain.dto.BlogArticlesDto;
import com.crocodileQ.blog.domain.vo.BlogArticlesVo;
import com.crocodileQ.common.constant.BlogConstants;
import com.crocodileQ.common.exception.base.BaseException;
import com.crocodileQ.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.crocodileQ.blog.mapper.BlogArticlesMapper;
import com.crocodileQ.blog.service.IBlogArticlesService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 文章管理Service业务层处理
 * 
 * @author crocodilePole
 * @date 2025-04-10
 */
@Service
public class BlogArticlesServiceImpl implements IBlogArticlesService 
{
    //    range 0:全部 1：已发布 2：草稿 3：回收站
    private static final String PUBLISHED = "1";
    private static final String DRAFT = "2";
    private static final String RECYCLE = "3";

    @Autowired
    private BlogArticlesMapper blogArticlesMapper;

    @Autowired
    private BlogArticleTagsServiceImpl blogArticleTagsService;

    @Autowired
    private BlogCommentsServiceImpl blogCommentsService;

    /**
     * 查询文章管理
     * 
     * @param id 文章管理主键
     * @return 文章管理
     */
    @Override
    public BlogArticlesVo selectBlogArticlesById(Long id)
    {
        BlogArticlesVo blogArticlesVo = blogArticlesMapper.selectBlogArticlesById(id);
        if (blogArticlesVo != null) {
            blogArticlesVo.setTagIds(blogArticleTagsService.selectBlogTagsByArticleId(blogArticlesVo.getId()));
            blogArticlesVo.setCommentCount(blogCommentsService.countByArticleId(id));
        }
        return blogArticlesVo;
    }

    /**
     * 查询文章管理列表
     *
     * @param blogArticlesDto 文章管理
     * @return 文章管理
     */
    @Override
    public List<BlogArticlesVo> selectBlogArticlesList(BlogArticlesDto blogArticlesDto)
    {

        String startDateStr = "01-01";
        String endDateStr = "12-31";
        String startDayStr = "01";
        String endDayStr ;
        String dateSplit = "-";
        // 1、判断日期
        //1.1、只有年，根据year字段转日期
        if (blogArticlesDto.getYear() != null && blogArticlesDto.getMonth() == null) {
            //startDate、endDate条件赋值
            blogArticlesDto.setStartDate(DateUtils.parseDate(blogArticlesDto.getYear() + dateSplit + startDateStr ));
            blogArticlesDto.setEndDate(DateUtils.parseDate(blogArticlesDto.getYear() + dateSplit + endDateStr));
        }else if(blogArticlesDto.getYear() != null){
            //1.2、年月皆有，根据年、月份处理天数
            endDayStr = getDay(blogArticlesDto.getYear(), blogArticlesDto.getMonth());
            if(endDayStr.equals("0")){
                throw new BaseException("日期错误");
            }
            //startDate、endDate条件赋值
            Date startDate = DateUtils.parseDate(blogArticlesDto.getYear() + dateSplit + blogArticlesDto.getMonth() + dateSplit + startDayStr);
            Date endDate = DateUtils.parseDate(blogArticlesDto.getYear() + dateSplit + blogArticlesDto.getMonth() + dateSplit + endDayStr);
            blogArticlesDto.setStartDate(startDate);
            blogArticlesDto.setEndDate(endDate);
        }
        //2、处理状态信息
        //range 0:全部 1：已发布 2：草稿 3：回收站
        String range = (String) blogArticlesDto.getParams().get("range");
        //默认查询全部文章
        if(range != null){
            switch (range) {
                case PUBLISHED://已发布
                    blogArticlesDto.setStatus(BlogConstants.BLOG_ARTICLES_STATUS_PUBLISHED);
                    break;
                case DRAFT://草稿
                    blogArticlesDto.setStatus(BlogConstants.BLOG_ARTICLES_STATUS_DRAFT);
                    break;
                case RECYCLE://回收站
                    blogArticlesDto.setDelFlag(BlogConstants.BLOG_DEL_TRUE);
                    break;
            }
        }
        List<BlogArticlesVo> blogArticles = blogArticlesMapper.selectBlogArticlesList(blogArticlesDto);

        //查询标签信息
        blogArticles = blogArticles.stream().peek(item -> {
            List<Long> tags = blogArticleTagsService.selectBlogTagsByArticleId(item.getId());
            item.setTagIds(tags);
        }).collect(Collectors.toList());


        return blogArticles;
    }


    /**
     * 根据年份和月份处理天数
     * @param year
     * @param month
     * @return
     */
    private String getDay(String year, String month) {
       //根据年份和月份处理天数
        if (year == null || month == null) {
            return "0";
        }
        int inYear = Integer.parseInt(year);
        switch (Integer.parseInt(month)) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return "31";
            case 4:
            case 6:
            case 9:
            case 11:
                return "30";
            case 2:
                if (inYear % 4 == 0 && inYear % 100 != 0 || inYear % 400 == 0) {
                    return "29";
                }else{
                    return "28";
                }
            default:
                return "0";
        }
    }


    /**
     * 新增文章管理
     * 
     * @param blogArticlesDto 文章管理
     * @return 结果
     */
    @Override
    public int insertBlogArticles(BlogArticlesDto blogArticlesDto)
    {
        blogArticlesDto.setCreateTime(DateUtils.getNowDate());
        //1、获取用户信息 个人博客用户id：6
        blogArticlesDto.setUserId(BlogConstants.BLOG_ARTICLE_USER_ID);
        //2、文章状态： 0：草稿 1：已发布 默认发布
        blogArticlesDto.setStatus(BlogConstants.BLOG_ARTICLES_STATUS_PUBLISHED);
        //3、文章发布时间
        blogArticlesDto.setPublishedTime(DateUtils.getNowDate());
        //4、文章删除标志：0：正常 1：删除
        blogArticlesDto.setDelFlag(BlogConstants.BLOG_DEL_FALSE);
        //5、新增文章
        int result = blogArticlesMapper.insertBlogArticles(blogArticlesDto);

        //批量插入文章和标签的关系
        BlogArticleTagsDto blogArticleTagsDto = new BlogArticleTagsDto();
        blogArticleTagsDto.setArticleId(blogArticlesDto.getId());
        blogArticleTagsDto.setTagIds(blogArticlesDto.getTagIds());

        blogArticleTagsService.batchInsertBlogArticleTags(blogArticleTagsDto);
        return result;
    }

    /**
     * 修改文章管理
     * 
     * @param blogArticlesDto 文章管理
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateBlogArticles(BlogArticlesDto blogArticlesDto)
    {
        blogArticlesDto.setUpdateTime(DateUtils.getNowDate());
        //更新标签信息
        //1、删除中间表标签和文章的信息
        blogArticleTagsService.deleteBlogArticleTagsByArticleIds(new Long[]{blogArticlesDto.getId()});
        //2、批量插入文章和标签的关系
        BlogArticleTagsDto blogArticleTagsDto = new BlogArticleTagsDto();
        blogArticleTagsDto.setArticleId(blogArticlesDto.getId());
        blogArticleTagsDto.setTagIds(blogArticlesDto.getTagIds());

        blogArticleTagsService.batchInsertBlogArticleTags(blogArticleTagsDto);

        return blogArticlesMapper.updateBlogArticles(blogArticlesDto);
    }

    /**
     * 批量删除文章管理
     * 
     * @param ids 需要删除的文章管理主键
     * @return 结果
     */
    @Override
    public int deleteBlogArticlesByIds(Long[] ids)
    {

        //1、删除中间表标签和文章的信息
        blogArticleTagsService.deleteBlogArticleTagsByArticleIds(ids);

        return blogArticlesMapper.deleteBlogArticlesByIds(ids);
    }

    /**
     * 删除文章管理信息
     * 
     * @param id 文章管理主键
     * @return 结果
     */
    @Override
    public int deleteBlogArticlesById(Long id)
    {
        return blogArticlesMapper.deleteBlogArticlesById(id);
    }

    /**
     * 根据用户id查询文章、已发布、草稿、回收站数量
     * @param userId
     * @return
     */
    public HashMap<String, Integer> countByUserId(Long userId) {
        HashMap<String, Integer> map = new HashMap<>();
        map.put("all", blogArticlesMapper.countByUserId(userId));
        map.put("published", blogArticlesMapper.countPublishedByUserId(userId));
        map.put("draft", blogArticlesMapper.countDraftByUserId(userId));
        map.put("recycle", blogArticlesMapper.countRecycleByUserId(userId));

        return map;
    }
}
